﻿using Microsoft.OpenApi.Any;
using Newtonsoft.Json;
using NSwag.Generation.Processors;
using NSwag.Generation.Processors.Contexts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace Nswag
{
    public class NswagFilter : IDocumentProcessor
    {
        public void Process(DocumentProcessorContext context)
        {
            Dictionary<string, Type> dict = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
            dict = GetAllEnum();
            Console.WriteLine(JsonConvert.SerializeObject(dict));

            foreach (var item in context.Document.Components.Schemas)
            {
                var property = item.Value;
                var typeName = item.Key;
                Type itemType = null;
                Console.WriteLine(JsonConvert.SerializeObject(item));

                if (property.IsEnumeration)
                {
                    itemType = dict.Where(o => o.Key.ToUpper().Contains(typeName.ToUpper())).Select(o => o.Value).FirstOrDefault();
                    List<int> list = new List<int>();
                    foreach (int val in property.Enumeration)
                    {
                        list.Add(val);
                    }

                    property.Description += DescribeEnum(itemType, list);
                }
            }
        }
        private static Dictionary<string, Type> GetAllEnum()
        {
            Assembly ass = Assembly.Load("Nswag");//枚举所在的命名空间

            Type[] types = ass.GetTypes();
            Dictionary<string, Type> dict = new Dictionary<string, Type>();

            foreach (Type item in types)
            {
                if (item.IsEnum)
                {
                    dict.Add(item.Name, item);
                }
            }
            return dict;
        }

        private static string DescribeEnum(Type type, List<int> enums)
        {
            var enumDescriptions = new List<string>();
            foreach (var item in enums)
            {
                if (type == null) continue;
                var value = Enum.Parse(type, item.ToString());
                var desc = GetDescription(type, value);

                if (string.IsNullOrEmpty(desc))
                    enumDescriptions.Add($"{item}={Enum.GetName(type, value)}");
                else
                    enumDescriptions.Add($"{item}={Enum.GetName(type, value)}（{desc}）");
            }
            return $"<br><div>{Environment.NewLine}{string.Join("<br/>" + Environment.NewLine, enumDescriptions)}</div>";
        }

        private static string GetDescription(Type t, object value)
        {
            foreach (MemberInfo mInfo in t.GetMembers())
            {
                if (mInfo.Name == t.GetEnumName(value))
                {
                    foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))
                    {
                        if (attr.GetType() == typeof(System.ComponentModel.DescriptionAttribute))
                        {
                            return ((System.ComponentModel.DescriptionAttribute)attr).Description;
                        }
                    }
                }
            }
            return string.Empty;
        }


    }
}
